﻿using AutoMapper;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Primitives;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace DFGK_WMS.Repository
{
    /// <summary>
    /// 编码规则
    /// </summary>
    public class BarCodeRuleRepository : BaseRepository<TBarCodeRule>, IBarCodeRuleRepository
    {
        public BarCodeRuleRepository(DFGK_DB context, IMapper mapper) : base(context, mapper)
        {
        }
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public bool AddCodeRule(BarCodeRuleDto dto)
        {
            try
            {
                string code = "BarCodeRules";
                var aobj = Context.TBarCodeRules.AsNoTracking().Where(x => x.Code.Contains(code)).OrderByDescending(x => x.CreateDate).FirstOrDefault();
                if (aobj != null)
                {
                    string pattern = @"\d+";
                    MatchCollection matches = Regex.Matches(aobj.Code, pattern);
                    string value = matches[matches.Count - 1].Value;
                    int values = Convert.ToInt32(value);
                    values++;
                    dto.Code = code + values.ToString("D4");
                }
                else
                {
                    int i = 1;
                    dto.Code = code + i.ToString("D4");
                }

                var bobj = Context.TBarCodeRules.AsNoTracking().FirstOrDefault(x => x.Type == dto.Type);
                if (bobj != null)
                {
                    return false;
                }
                foreach (var item in Enum.GetValues<CodeRulesType>())
                {
                    if (item == (CodeRulesType)dto.Type)
                    {
                        dto.Code = item.ToString();
                    }
                }
                TBarCodeRule codeRule = new TBarCodeRule()
                {
                    Code = dto.Code,
                    Name = dto.Name,
                    Type = dto.Type,
                    RuleDescription = dto.RuleDescription,
                    BarCodeRules = dto.BarCodeRules,
                    MaxNumber = dto.MaxNumber,
                    NumberLength = dto.NumberLength,
                    StartNumber = dto.StartNumber,
                    Number = dto.Number,
                    IsEnable = dto.IsEnable,
                    CreateDate = DateTime.Now,
                    CreateUserId = dto.NowUserId,
                    CreateUserName = dto.NowUserRealName
                };
                codeRule.Sample = GetBarCodeSample(codeRule) + "00001";
                Context.TBarCodeRules.Add(codeRule);
                return Context.SaveChanges() > 0;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public bool UpdateCodeRule(BarCodeRuleDto dto)
        {
            try
            {
                var bobj = Context.TBarCodeRules.AsNoTracking().FirstOrDefault(x => x.Id != dto.Id && x.Type == dto.Type);
                if (bobj != null)
                {
                    return false;
                }

                foreach (var item in Enum.GetValues<CodeRulesType>())
                {
                    if (item == (CodeRulesType)dto.Type)
                    {
                        dto.Code = item.ToString();
                    }
                }
                TBarCodeRule codeRule = new TBarCodeRule()
                {
                    Id = dto.Id,
                    Code = dto.Code,
                    Name = dto.Name,
                    Type = dto.Type,
                    RuleDescription = dto.RuleDescription,
                    BarCodeRules = dto.BarCodeRules,
                    MaxNumber = dto.MaxNumber,
                    NumberLength = dto.NumberLength,
                    StartNumber = dto.StartNumber,
                    Number = dto.Number,
                    IsEnable = dto.IsEnable,
                    ModifyDate = DateTime.Now,
                    ModifyUserId = dto.NowUserId,
                    ModifyUserName = dto.NowUserRealName,
                    CreateDate = dto.CreateDate,
                    CreateUserId = dto.NowUserId,
                    CreateUserName = dto.NowUserRealName

                };
                codeRule.Sample = GetBarCodeSample(codeRule) + "00001";
                Context.TBarCodeRules.Update(codeRule);
                return Context.SaveChanges() > 0;
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public bool DelCodeRule(int ids)
        {
            try
            {
                var rules = Context.TBarCodeRules.Find(ids);
                Context.TBarCodeRules.Remove(rules);
                return Context.SaveChanges() > 0;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        public List<TBarCodeRule> GetCodeRules(string name, int pageIndex, int pageSize, out int totalCount)
        {
            try
            {
                var list = Context.TBarCodeRules.AsQueryable();
                if (!string.IsNullOrEmpty(name))
                {
                    list = list.Where(x => x.Name.Contains(name));
                }
                list = list.OrderByDescending(x => x.CreateDate).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                totalCount = list.Count();
                return list.ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 条件查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TBarCodeRule GetCodeRule(int id)
        {
            return Context.TBarCodeRules.Find(id);
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <returns></returns>
        public List<TBarCodeRule> GetCodeRulest()
        {
            return Context.TBarCodeRules.AsQueryable().ToList();

        }

        /// <summary>
        /// 获取编码规则
        /// </summary>
        /// <param name="type">编码类型</param>
        /// <returns>编码示例</returns>
        /// <exception cref="NotImplementedException"></exception>
        public string GetBarCodeSample(int type)
        {
            var bobj = Context.TBarCodeRules
                .AsNoTracking()
                .FirstOrDefault(x => x.Type == type && x.IsEnable == true);

            if (bobj != null)
            {
                string value = GetBarCodeSample(bobj) ?? "此处有误！";
                string result = "";

                //for (int i = 1; ; i++)
                //{
                //    string iStr = i.ToString("D5");
                //    result = $"{value}{iStr}";

                //    var obj = Context.TReceivingOrderDetails
                //        .AsNoTracking()
                //        .FirstOrDefault(x => x.OrderSn == result);

                switch (type)
                {
                    case 0:
                        break;
                    case 1:
                        result = GetInOrderBarCode(result, value);
                        if (!string.IsNullOrEmpty(result))
                        {
                            return result;
                        }
                        break;
                    case 2:
                        result = GetOutOrderBarCode(result, value);
                        if (!string.IsNullOrEmpty(result))
                        {
                            return result;
                        }
                        break;
                    case 3:
                        break;
                    case 4:
                        result = GetPalletBarCode(result, value);
                        if (!string.IsNullOrEmpty(result))
                        {
                            return result;
                        }
                        break;
                    case 5:
                        result = GetBox8060BarCode(result, value);
                        if (!string.IsNullOrEmpty(result))
                        {
                            return result;
                        }
                        break;
                    case 6:
                        result = GetBox6040BarCode(result, value);
                        if (!string.IsNullOrEmpty(result))
                        {
                            return result;
                        }
                        break;                 
                    default:
                        break;
                }

                //    if (obj != null)
                //    {
                //        continue;
                //    }
                //    else
                //    {
                //        return result;
                //    }
                //}
            }

            return null;
        }

        /// <summary>
        /// 静态方法获取编码规则
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public static string GetBarCodeSample(TBarCodeRule m)
        {
            var result = new StringBuilder();
            DateTime date = DateTime.Now;
            var barcoderules = m.BarCodeRules.Split(',');

            foreach (var item in barcoderules)
            {
                switch (Convert.ToInt32(item))
                {
                    case 0:
                        int startIndex = m.RuleDescription.IndexOf("%文本框") + "%文本框".Length;
                        int endIndex = m.RuleDescription.IndexOf("%", startIndex);

                        if (startIndex != -1 && endIndex != -1)
                        {
                            string tpw = m.RuleDescription.Substring(startIndex, endIndex - startIndex);
                            result.Append(tpw);
                        }
                        else
                        {
                            result.Append("文本框有误！");
                        }
                        break;
                    case 1:
                        result.Append(date.ToString("yyyy"));
                        break;
                    case 2:
                        result.Append(date.ToString("MM"));
                        break;
                    case 3:
                        result.Append(date.Day);
                        break;
                    case 4:
                        result.Append(date.ToString("HH"));
                        break;
                    case 5:
                        int weeknow = (int)date.DayOfWeek;
                        if (weeknow == 0)
                        {
                            result.Append(7);
                        }
                        else
                        {
                            result.Append(weeknow);
                        }
                        break;
                    case 6:
                        string year = date.ToString("yyyy");
                        result.Append(year.Substring(2, 2));
                        break;
                    case 7:
                        result.Append(m.Number);
                        break;
                    default:
                        result = null;
                        break;
                }
            }
            return result?.ToString();
        }

       ///// <summary>
       ///// 工单
       ///// </summary>
       ///// <param name="result"></param>
       ///// <param name="value"></param>
       ///// <returns></returns>
       // public string GetWorkOrderBarCode(string result, string value)
       // {
       //     for (int i = 1; ; i++)
       //     {
       //         string iStr = i.ToString("D5");
       //         result = $"{value}{iStr}";

       //         var obj = Context.TReceivingOrderDetails
       //             .AsNoTracking()
       //             .FirstOrDefault(x => x.OrderSn == result);
       //         if (obj != null)
       //         {
       //             continue;
       //         }
       //         else
       //         {
       //             return result;
       //         }
       //     }
       // }

        /// <summary>
        /// 入库单编码
        /// </summary>
        /// <param name="result"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string GetInOrderBarCode(string result, string value)
        {
            for (int i = 1; ; i++)
            {
                string iStr = i.ToString("D7");
                result = $"{value}{iStr}";

                var obj = Context.TReceivingOrderDetails
                    .AsNoTracking()
                    .FirstOrDefault(x => x.OrderSn == result);
                if (obj != null)
                {
                    continue;
                }
                else
                {
                    return result;
                }
            }
        }

        /// <summary>
        /// 出库单编码
        /// </summary>
        /// <param name="result"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string GetOutOrderBarCode(string result, string value)
        {
            for (int i = 1; ; i++)
            {
                string iStr = i.ToString("D7");
                result = $"{value}{iStr}";

                var obj = Context.TShippingOrderDetails
                    .AsNoTracking()
                    .FirstOrDefault(x => x.OrderSn == result);
                if (obj != null)
                {
                    continue;
                }
                else
                {
                    return result;
                }
            }
        }

        /// <summary>
        /// 托盘编码
        /// </summary>
        /// <param name="result"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string GetPalletBarCode(string result, string value)
        {
            for (int i = 1; ; i++)
            {
                string iStr = i.ToString("D7");
                var sjs = new Random();
                result = $"{value}{iStr}{sjs.Next(1000,9999)}";

                var obj = Context.TPallets
                    .AsNoTracking()
                    .FirstOrDefault(x => x.PalletBarcode == result);
                if (obj != null)
                {
                    continue;
                }
                else
                {
                    return result;
                }
            }
        }

        /// <summary>
        /// 料箱800*600编码
        /// </summary>
        /// <param name="result"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string GetBox8060BarCode(string result, string value)
        {
            for (int i = 1; ; i++)
            {
                string iStr = i.ToString("D7");
                result = $"{value}{iStr}";

                var obj = Context.TPallets
                    .AsNoTracking()
                    .FirstOrDefault(x => x.PalletBarcode == result);
                if (obj != null)
                {
                    continue;
                }
                else
                {
                    return result;
                }
            }
        }

        /// <summary>
        /// 料箱600*400编码
        /// </summary>
        /// <param name="result"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string GetBox6040BarCode(string result, string value)
        {
            for (int i = 1; ; i++)
            {
                string iStr = i.ToString("D7");
                result = $"{value}{iStr}";

                var obj = Context.TPallets
                    .AsNoTracking()
                    .FirstOrDefault(x => x.PalletBarcode == result);
                if (obj != null)
                {
                    continue;
                }
                else
                {
                    return result;
                }
            }
        }
    }
}
